/**
 * 
 */
package sap.provider;

import com.sap.mw.jco.JCO;

import sap.Connection;
import data.Milestone;
import data.ReturnValue;

/**
 * @author sebastian
 *
 */
public final class Stone implements Methods {
	public static Milestone get(String project, String pspElement, String milestone) {
		Milestone[] list = get(project, pspElement);
		
		for (int i=0; i<list.length; i++) {
            //System.out.println(list[i].milestone_number);
			if (Integer.parseInt(list[i].milestone_number) == Integer.parseInt(milestone))
				return list[i];
        }
		
		return null;
	}
	
	public static Milestone[] get(String project, String pspElement) {
		// TODO find exceptions
		Connection con = Connection.getInstance();
		
		JCO.Function function = con.getFunction("BAPI_PROJECT_GETINFO");
		
		// fill import parameter
		function.getImportParameterList().setValue("X", "WITH_MILESTONES");
		// TODO need project definition?
		JCO.Table t = function.getTableParameterList().getTable("I_WBS_ELEMENT_TABLE");
		//System.out.println(t);
		t.appendRow();
		t.setValue(pspElement, "WBS_ELEMENT");
		//t.setValue(project, "PROJECT_DEFINITION");
		
		con.execute(function);
		
		ReturnValue r = Return.getFromStructure(function.
				getExportParameterList().getStructure("RETURN"));
		ReturnValue[] detail = Return.getFromTable(function.
				getTableParameterList().getTable("E_MESSAGE_TABLE"));
		Return.testReturnValue(r, detail);
		
		t = function.getTableParameterList().getTable("E_WBS_MILESTONE_TABLE");
		int num = t.getNumRows();
		Milestone[] result = new Milestone[num];
		for (int i=0; i<num; i++) {
			result[i] = classFromStruct(t);
			t.nextRow();
		}
		
		return result;
	}
	
	public static void create(Milestone stone) {
		maintain(stone, CREATE_METHOD);
	}
	
	public static void maintain(Milestone stone) {
		maintain(stone, UPDATE_METHOD);
	}
	
	public static void delete(String pspElement, String milestone) {
		Milestone stone = new Milestone();
		stone.wbs_element = pspElement;
		stone.milestone_number = milestone;
		
		delete(stone);
	}
	
	public static void delete(Milestone stone) {
		maintain(stone, DELETE_METHOD);
	}
	
	private static void maintain(Milestone stone, String method) {
		Connection con = Connection.getInstance();
		
		JCO.Function function = con.getFunction("BAPI_PROJECT_MAINTAIN");
		
		// fill import parameter
		JCO.ParameterList tables = function.getTableParameterList();
		JCO.Table t = tables.getTable("I_METHOD_PROJECT");
		t.appendRow();
		t.setValue("WBS-Milestone", "OBJECTTYPE");
		t.setValue(method, "METHOD");
		t.setValue(stone.milestone_number, "OBJECTKEY");
		t.setValue(1, "REFNUMBER");
		t.appendRow();
		t.setValue("Save", "METHOD");
		t = tables.getTable("I_WBS_MILESTONE_TABLE");
		t.appendRow();
		structFromClass(stone, t);
		if (method.equals(UPDATE_METHOD)) {
			t = tables.getTable("I_WBS_MILESTONE_TABLE_UPDATE");
			t.appendRow();
			Connection.fillX(t, 2);
		}
		
		con.execute(function);
		
		ReturnValue r = Return.getFromStructure(function.
				getExportParameterList().getStructure("RETURN"));
		ReturnValue[] detail = Return.getFromTable(function.
				getTableParameterList().getTable("E_MESSAGE_TABLE"));
		Return.testReturnValue(r, detail);
	}
	
	private static Milestone classFromStruct(JCO.Record struct) {
		Milestone result = new Milestone();
		
		result.milestone_number = struct.getString(0);
		result.wbs_element = struct.getString(1);
		result.milestone_usage = struct.getString(2);
		result.description = struct.getString(3);
		result.sched_milestone_date_basic = struct.getString(4);
		result.sched_milestone_time_basic = struct.getString(5);
		result.sched_milestone_date_forecast = struct.getString(6);
		result.sched_milestone_time_forecast = struct.getString(7);
		result.fixed_milestone_date_basic = struct.getString(8);
		result.fixed_milestone_time_basic = struct.getString(9);
		result.fixed_milestone_date_forecast = struct.getString(10);
		result.fixed_milestone_time_forecast = struct.getString(11);
		result.actual_date = struct.getString(12);
		result.actual_time = struct.getString(13);
		result.latest_dates_indicator = struct.getString(14);
		result.offset_start_end_indicator = struct.getString(15);
		result.offset_milestone_date = struct.getString(16);
		result.offset_milestone_date_unit = struct.getString(17);
		result.offset_milestone_date_unit_iso = struct.getString(18);
		result.offset_percentage = struct.getString(19);
		result.trend_analysis_indicator = struct.getString(20);
		result.earned_value_indicator = struct.getString(21);
		result.percentage_of_completion = struct.getString(22);
		result.sales_doc_date_inidicator = struct.getString(23);
		result.invoice_percentage = struct.getString(24);
		result.deletion_flag = struct.getString(25);
		
		return result;
	}
	
	private static void structFromClass(Milestone stone, JCO.Record struct) {
		struct.setValue(stone.milestone_number, 0);
		struct.setValue(stone.wbs_element, 1);
		struct.setValue(stone.milestone_usage, 2);
		struct.setValue(stone.description, 3);
		struct.setValue(stone.sched_milestone_date_basic, 4);
		struct.setValue(stone.sched_milestone_time_basic, 5);
		struct.setValue(stone.sched_milestone_date_forecast, 6);
		struct.setValue(stone.sched_milestone_time_forecast, 7);
		struct.setValue(stone.fixed_milestone_date_basic, 8);
		struct.setValue(stone.fixed_milestone_time_basic, 9);
		struct.setValue(stone.fixed_milestone_date_forecast, 10);
		struct.setValue(stone.fixed_milestone_time_forecast, 11);
		struct.setValue(stone.actual_date, 12);
		struct.setValue(stone.actual_time, 13);
		struct.setValue(stone.latest_dates_indicator, 14);
		struct.setValue(stone.offset_start_end_indicator, 15);
		struct.setValue(stone.offset_milestone_date, 16);
		struct.setValue(stone.offset_milestone_date_unit, 17);
		struct.setValue(stone.offset_milestone_date_unit_iso, 18);
		struct.setValue(stone.offset_percentage, 19);
		struct.setValue(stone.trend_analysis_indicator, 20);
		struct.setValue(stone.earned_value_indicator, 21);
		struct.setValue(stone.percentage_of_completion, 22);
		struct.setValue(stone.sales_doc_date_inidicator, 23);
		struct.setValue(stone.invoice_percentage, 24);
	}
}
